﻿using System;
using System.Collections.Generic;
using System.Text;
using MagicApp.Services;
using NUnit.Framework;
using MagicApp.Data;
using MagicApp.Data.Creature;

namespace MagicApp.Testing
{
    [TestFixture]
    public class DeckEngineTests
    {
        [Test]
        public void GetDeckByName_Should_Return_A_Deck_By_Name_Of_Sammys()
        {
            DeckEngine de = new DeckEngine(new DummyCardRepository());
            Assert.AreEqual("sammys", de.GetDeck("sammys").DeckName.ToLower(), "Should have returned Deck name of Sammy's");
        }
        [Test]
        public void GetDeckByName_Should_Return_a_deck_with_10_cards_in_it()
        {
            DeckEngine de = new DeckEngine(new DummyCardRepository());
            Assert.AreEqual(10, de.GetDeck("sammys").GetNumberOfCardsInDeck(), "should ahve been 10 cards");
        }
        [Test]
        public void AddToCurrentDeck_Should_Add_A_Card_To_The_Current_Added_Deck()
        {
        	DeckEngine de = new DeckEngine(new DummyCardRepository());
        	Card newCard = new Creature();
        	de.AddToCurrentDeck(newCard);
        	Assert.AreEqual(1,de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(),"Should be 1");
        }
        [Test]
        public void DeleteCurrentDeck_Should_Delete_Currently_Edited_Deck()
        {
        	DeckEngine de = new DeckEngine(new DummyCardRepository());
        		Card newCard = new Creature();
        	de.AddToCurrentDeck(newCard);
        	Assert.AreEqual(1, de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(),"Should be only 1 added");
        	de.DeleteCurrentDeck();
        	Assert.AreEqual(0, de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(),"Deck should be empty");	
        }
        [Test]
        public void SaveCurrentDeck_Should_Return_true_if_save_is_complete()
        {
        	DeckEngine de = new DeckEngine(new DummyCardRepository());
        	de.CreateNewDeck("sammys");
        	Assert.IsTrue(de.SaveCurrentDeck());
        }
        [Test]
        public void Complete_Card_LifeCycle()
        {
        	DeckEngine de = new DeckEngine(new DummyCardRepository());
        	de.CreateNewDeck("monkey");
        	Assert.AreEqual(50, de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(),"should be 50");
        	Assert.AreEqual("monkey", de.GetCurrentlyEditedDeck().DeckName, "should be monkey");
        	Creature creature = new Creature();
        	de.AddToCurrentDeck(creature);
        	Assert.AreEqual(51, de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(),"Should be 51");
        	de.DeleteFromCurrentDeck(creature);
        	Assert.AreEqual(50, de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(),"Should be 50");
        	
        }
        [Test]
        public void DeckExists_Returns_False_if_Deck_Doesnt_Exist()
        {
        	DeckEngine de = new DeckEngine(new DummyCardRepository());
        	Assert.IsFalse(de.DeckExists("monkopopop"));
        	Assert.IsTrue(de.DeckExists("sammys"));
        	
        }
        [Test]
        public void PopulateHand_Should_Populate_A_Hand_Of_7_Cards()
        {
        	IDeckEngine de = new DeckEngine(new DummyCardRepository());
        	de.CreateNewDeck("monkeyBalls");
        	de.PopulateHand();
            Assert.AreEqual(7,de.GetCurrentHand().GetCurrentHandCount(), "Should equal 7");
            
        }

        [Test]
        public void CurrentHand_Should_Contain_A_Card_of_Card_Name_Monkey()
        {
            IDeckEngine de = new DeckEngine(new DummyCardRepository());
            de.CreateNewDeck("monkeyBalls");
            de.PopulateHand();
            Hand hand = de.GetCurrentHand();
            IList<Card> cards = hand.GetCurrentHand();
            for (int i = 0; i < cards.Count; i++)
            {
                if(cards[i].CardName == "monkey")
                {
                    Assert.AreEqual(CardType.Sorcery.ToString(),cards[i].CardType.ToString(),"should be sorcery");
                    Console.WriteLine(cards[i].CardName + " " + cards[i].CardID.ToString());
                }
            }
        }
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void Populate_hand_shouldnt_work_without_a_deck_existing()
        {
            IDeckEngine de = new DeckEngine(new DummyCardRepository());
            de.PopulateHand();
        }

        [Test]
        public void ReturnTopOfDeck_should_return_the_top_of_deck_with_cardname_of_monkey()
        {
            IDeckEngine de = new DeckEngine(new DummyCardRepository());
            de.CreateNewDeck("monkey");
            Assert.AreEqual("monkey",de.DrawFromCurrentDeck().CardName,"should return monkey");
        }
        [Test]
        public void PopulateHand_Should_Decrement_the_deck_by_7_Cards()
        {
        	IDeckEngine de = new DeckEngine(new DummyCardRepository());
            de.CreateNewDeck("monkey");
            de.PopulateHand();
            Assert.AreEqual(43,de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(),"should be 47");
        }
        [Test]
        public void DrawCard_Should_Decrement_The_Deck_and_add_to_the_Hand()
        {
        	IDeckEngine de = new DeckEngine(new DummyCardRepository());
            de.CreateNewDeck("monkey");
            de.PopulateHand();
            de.GetCurrentHand().Add(de.DrawFromCurrentDeck());
            Assert.AreEqual(8, de.GetCurrentHand().GetCurrentHandCount(), "should be 8 cards");
            Assert.AreNotEqual(49, de.GetCurrentlyEditedDeck().GetNumberOfCardsInDeck(), "Should be 49 cards");
        }
        [Test]
        public void Hand_ReturnRandomCard_should_return_a_card_less_than_the_total_hand()
        {
            IDeckEngine de = new DeckEngine(new DummyCardRepository());
            de.CreateNewDeck("monkey");
            de.PopulateHand();
            Card card = de.GetCurrentHand().ReturnRandomCardInHand();
            int indexOf = de.GetCurrentHand().GetCurrentHand().IndexOf(card);
            Assert.IsNotNull(indexOf);
            Assert.IsTrue(indexOf <=6);
        }
        
        
        
    }
}
